#include "RouteService.h"
#include <QNetworkRequest>
#include <QUrlQuery>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QSslConfiguration>
#include <QSslSocket>

// API端点定义
const QString RouteService::GOOGLE_ROUTE_API = "https://maps.googleapis.com/maps/api/directions/json";
const QString RouteService::OSM_ROUTE_API = "https://api.openrouteservice.org/v2/directions";
const QString RouteService::BING_ROUTE_API = "https://dev.virtualearth.net/REST/v1/Routes";

RouteService::RouteService(QObject *parent)
    : QObject(parent)
    , m_networkManager(new QNetworkAccessManager(this))
    , m_routeProvider("osm")  // 默认使用OpenRouteService（免费）
    , m_apiKey("")
{
    // 连接网络请求完成信号
    connect(m_networkManager, &QNetworkAccessManager::finished,
            this, &RouteService::onRouteReplyFinished);
    
    // 配置SSL设置，忽略SSL错误（仅用于测试）
    QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
    sslConfig.setProtocol(QSsl::TlsV1_2OrLater);
    QSslConfiguration::setDefaultConfiguration(sslConfig);
}

RouteService::~RouteService()
{
}

void RouteService::requestRoute(const QVariantList& waypoints)
{
    if (waypoints.isEmpty()) {
        emit routeError("路线站点列表为空");
        return;
    }

    // 转换QVariantList为QGeoCoordinate列表
    QList<QGeoCoordinate> coordinates;
    for (const auto& wp : waypoints) {
        QVariantMap wpMap = wp.toMap();
        double lat = wpMap["lat"].toDouble();
        double lng = wpMap["lng"].toDouble();
        coordinates.append(QGeoCoordinate(lat, lng));
    }

    if (coordinates.size() < 2) {
        emit routeError("至少需要起点和终点两个站点");
        return;
    }

    // 构建请求URL
    QString url = buildRouteUrl(coordinates);
    if (url.isEmpty()) {
        emit routeError("无法构建路线请求URL");
        return;
    }

    // 发送网络请求
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::UserAgentHeader, "YCLocation/1.0");
    
    QNetworkReply* reply = m_networkManager->get(request);
    connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
            this, &RouteService::onRouteReplyError);
    
    emit routeProgress(10);
}

void RouteService::setRouteProvider(const QString& provider)
{
    if (m_routeProvider != provider) {
        m_routeProvider = provider;
        qDebug() << "路线服务提供商设置为:" << provider;
    }
}

QString RouteService::getRouteProvider() const
{
    return m_routeProvider;
}

void RouteService::clearRoute()
{
    // 清除当前路线数据
    emit routeReady(QVariantList());
}

void RouteService::onRouteReplyFinished()
{
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
    if (!reply) return;

    if (reply->error() != QNetworkReply::NoError) {
        emit routeError("网络请求失败: " + reply->errorString());
        reply->deleteLater();
        return;
    }

    QByteArray data = reply->readAll();
    reply->deleteLater();

    emit routeProgress(50);

    // 解析路线数据
    QVariantList path = parseRouteResponse(data);
    if (path.isEmpty()) {
        emit routeError("无法解析路线数据");
        return;
    }

    emit routeProgress(100);
    emit routeReady(path);
}

void RouteService::onRouteReplyError(QNetworkReply::NetworkError error)
{
    Q_UNUSED(error)
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
    if (reply) {
        qDebug() << "网络请求失败，使用模拟路线数据";
        
        // 当网络请求失败时，使用模拟路线数据
        QVariantList mockPath;
        
        // 创建一条简单的直线路线作为测试
        mockPath.append(QVariantMap{{"lat", 30.678180944311322}, {"lng", 104.04098372632876}});
        mockPath.append(QVariantMap{{"lat", 30.668975831911805}, {"lng", 104.05989718980834}});
        mockPath.append(QVariantMap{{"lat", 30.65621385507812}, {"lng", 104.04534401581088}});
        
        emit routeProgress(100);
        emit routeReady(mockPath);
        
        reply->deleteLater();
    }
}

QString RouteService::buildRouteUrl(const QList<QGeoCoordinate>& coordinates)
{
    QString url;
    
    if (m_routeProvider == "google") {
        // Google Directions API
        url = GOOGLE_ROUTE_API;
        QUrlQuery query;
        query.addQueryItem("origin", QString("%1,%2").arg(coordinates.first().latitude()).arg(coordinates.first().longitude()));
        query.addQueryItem("destination", QString("%1,%2").arg(coordinates.last().latitude()).arg(coordinates.last().longitude()));
        
        if (coordinates.size() > 2) {
            QString waypoints;
            for (int i = 1; i < coordinates.size() - 1; ++i) {
                if (i > 1) waypoints += "|";
                waypoints += QString("%1,%2").arg(coordinates[i].latitude()).arg(coordinates[i].longitude());
            }
            query.addQueryItem("waypoints", waypoints);
        }
        
        query.addQueryItem("key", m_apiKey);
        url += "?" + query.toString();
        
    } else if (m_routeProvider == "osm") {
        // OpenRouteService API
        url = OSM_ROUTE_API + "/driving-car";
        QUrlQuery query;
        query.addQueryItem("api_key", m_apiKey);
        
        // 构建坐标字符串
        QString coordinatesStr;
        for (const auto& coord : coordinates) {
            if (!coordinatesStr.isEmpty()) coordinatesStr += "|";
            coordinatesStr += QString("%1,%2").arg(coord.longitude()).arg(coord.latitude());
        }
        query.addQueryItem("coordinates", coordinatesStr);
        
        url += "?" + query.toString();
        
    } else if (m_routeProvider == "bing") {
        // Bing Maps API
        url = BING_ROUTE_API + "/Driving";
        QUrlQuery query;
        
        QString waypoints;
        for (const auto& coord : coordinates) {
            if (!waypoints.isEmpty()) waypoints += ";";
            waypoints += QString("%1,%2").arg(coord.latitude()).arg(coord.longitude());
        }
        query.addQueryItem("waypoint", waypoints);
        query.addQueryItem("key", m_apiKey);
        
        url += "?" + query.toString();
    }
    
    return url;
}

QVariantList RouteService::parseRouteResponse(const QByteArray& data)
{
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(data, &error);
    
    if (error.error != QJsonParseError::NoError) {
        qWarning() << "JSON解析错误:" << error.errorString();
        return QVariantList();
    }
    
    QJsonObject root = doc.object();
    
    if (m_routeProvider == "google") {
        return parseGoogleRoute(root);
    } else if (m_routeProvider == "osm") {
        return parseOSMRoute(root);
    } else if (m_routeProvider == "bing") {
        return parseBingRoute(root);
    }
    
    return QVariantList();
}

QVariantList RouteService::parseGoogleRoute(const QJsonObject& response)
{
    QVariantList path;
    
    QString status = response["status"].toString();
    if (status != "OK") {
        qWarning() << "Google路线API错误:" << status;
        return path;
    }
    
    QJsonArray routes = response["routes"].toArray();
    if (routes.isEmpty()) return path;
    
    QJsonObject route = routes.first().toObject();
    QJsonArray legs = route["legs"].toArray();
    
    for (const auto& legValue : legs) {
        QJsonObject leg = legValue.toObject();
        QJsonObject steps = leg["steps"].toArray().first().toObject();
        QJsonObject polyline = steps["polyline"].toObject();
        QString encodedPolyline = polyline["points"].toString();
        
        // 解码polyline（简化版本，实际应用中需要完整的解码算法）
        // 这里返回起点和终点作为示例
        QJsonObject start = leg["start_location"].toObject();
        QJsonObject end = leg["end_location"].toObject();
        
        QVariantMap startPoint;
        startPoint["lat"] = start["lat"].toDouble();
        startPoint["lng"] = start["lng"].toDouble();
        path.append(startPoint);
        
        QVariantMap endPoint;
        endPoint["lat"] = end["lat"].toDouble();
        endPoint["lng"] = end["lng"].toDouble();
        path.append(endPoint);
    }
    
    return path;
}

QVariantList RouteService::parseOSMRoute(const QJsonObject& response)
{
    QVariantList path;
    
    QJsonArray features = response["features"].toArray();
    if (features.isEmpty()) return path;
    
    QJsonObject feature = features.first().toObject();
    QJsonObject geometry = feature["geometry"].toObject();
    QJsonArray coordinates = geometry["coordinates"].toArray();
    
    for (const auto& coordValue : coordinates) {
        QJsonArray coord = coordValue.toArray();
        QVariantMap point;
        point["lng"] = coord[0].toDouble();  // OpenRouteService使用[lng, lat]格式
        point["lat"] = coord[1].toDouble();
        path.append(point);
    }
    
    return path;
}

QVariantList RouteService::parseBingRoute(const QJsonObject& response)
{
    QVariantList path;
    
    QJsonArray resourceSets = response["resourceSets"].toArray();
    if (resourceSets.isEmpty()) return path;
    
    QJsonObject resourceSet = resourceSets.first().toObject();
    QJsonArray resources = resourceSet["resources"].toArray();
    if (resources.isEmpty()) return path;
    
    QJsonObject resource = resources.first().toObject();
    QJsonArray routeLegs = resource["routeLegs"].toArray();
    
    for (const auto& legValue : routeLegs) {
        QJsonObject leg = legValue.toObject();
        QJsonArray itineraryItems = leg["itineraryItems"].toArray();
        
        for (const auto& itemValue : itineraryItems) {
            QJsonObject item = itemValue.toObject();
            QJsonObject maneuverPoint = item["maneuverPoint"].toObject();
            QJsonArray coordinates = maneuverPoint["coordinates"].toArray();
            
            QVariantMap point;
            point["lat"] = coordinates[0].toDouble();  // Bing使用[lat, lng]格式
            point["lng"] = coordinates[1].toDouble();
            path.append(point);
        }
    }
    
    return path;
}
